﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.TextEditor.Document;
using Openlab.Tools.CodeGender.StoredProcedures;
using Openlab.Tools.CodeGender.Funtions;
using Openlab.Tools.CodeGender.Classes;
using CarolLib.Tools.CodeGender.Coder.Classes;

namespace Openlab.Tools.CodeGender
{
    public partial class frmMain : Form
    {
        string currentTable = null;
        public frmMain()
        {
            InitializeComponent();
            //LoadData();
        }

        private void lvColumns_Resize(object sender, EventArgs e)
        {
            chRemarks.Width = lvColumns.Width - chName.Width - chIsPrimaryKey.Width - chTypeName.Width - 5;
        }

        private void btnGenerateEntity_Click(object sender, EventArgs e)
        {
            List<Column> columns = CodeOption.Columns;
            Column idColumn = CodeOption.IdColumn;
            if (!string.IsNullOrEmpty(currentTable) && columns.Count > 0)
            {
                Class c = new EntityClass(CodeOption);
                editorEntity.Text = c.Code;
                Class d = new QueryEntityClass(CodeOption);
                editorQueryEntity.Text = d.Code;
                GenerateSqlCode(CodeOption);
                GenerateDataAccessCode(CodeOption);
                GenerateManagerCode(idColumn);
            }
        }

        private void GenerateManagerCode(Column idColumn)
        {
            StringBuilder code = new StringBuilder();


            Class manager = new ManagerClass(CodeOption);
            code.AppendLine(manager.Code);

            editorManager.Text = code.ToString();
        }

        private void GenerateDataAccessCode(CodeOption option)
        {
            StringBuilder code = new StringBuilder();

            code.AppendLine();

            code.AppendFormat("#region {0}", option.ClassName);
            code.AppendLine();
            code.AppendLine();

            Function funCreateEntity = new CreateEntityDAFunc(option.ClassName, option.CreateEntityStoredProcedureName, option.Columns, option.IdColumn, option.EnableParamCache, option.GetNewAutoGUID);
            code.Append(funCreateEntity.Code);
            code.AppendLine();

            if (option.CreateBatOperation)
            {
                Function batfunCreateEntity = new BatCreateDAFunc(option.ClassName, option.CreateEntityStoredProcedureName + "_Bat", option.Columns, option.IdColumn, option.EnableParamCache, option.GetNewAutoGUID);
                code.Append(batfunCreateEntity.Code);
                code.AppendLine();
            }

            Function funUpdateEntity = new UpdateEntityDAFunc(option.ClassName, option.UpdateEntityStoredProcedureName, option.Columns, option.IdColumn, option.EnableParamCache);
            code.Append(funUpdateEntity.Code);
            code.AppendLine();

            Function funDeleteEntity = new DeleteEntityDAFunc(option.ClassName, option.DeleteEntityStoredProcedureName, option.IdColumn);
            code.Append(funDeleteEntity.Code);
            code.AppendLine();

            if (option.WithTrans)
            {
                Function funCreateEntityT = new CreateEntityDAFunc(option.ClassName, option.CreateEntityStoredProcedureName, option.Columns, option.IdColumn, option.EnableParamCache, option.GetNewAutoGUID, true);
                code.Append(funCreateEntityT.Code);
                code.AppendLine();

                Function batfunCreateEntityT = new BatCreateDAFunc(option.ClassName, option.CreateEntityStoredProcedureName, option.Columns, option.IdColumn, option.EnableParamCache, option.GetNewAutoGUID, true);
                code.Append(batfunCreateEntityT.Code);
                code.AppendLine();

                Function funUpdateEntityT = new UpdateEntityDAFunc(option.ClassName, option.UpdateEntityStoredProcedureName, option.Columns, option.IdColumn, option.EnableParamCache, true);
                code.Append(funUpdateEntityT.Code);
                code.AppendLine();

                Function funDeleteEntityT = new DeleteEntityDAFunc(option.ClassName, option.DeleteEntityStoredProcedureName, option.IdColumn, true);
                code.Append(funDeleteEntityT.Code);
                code.AppendLine();
            }

            Function fun1 = new GetEntityIdsDAFunc(option.ClassName, txtGetIdsStoredProcedureName.Text, option.IdColumn);
            code.Append(fun1.Code);
            code.AppendLine();

            Function fun2 = new GetEntitiesDAFunc(option.ClassName, txtGetEntitiesStoredProcedureName.Text, option.IdColumn);
            code.Append(fun2.Code);
            code.AppendLine();

            code.AppendLine();
            code.AppendFormat("#endregion");

            editorDataAccess.Text = code.ToString();
        }

        private void GenerateSqlCode(CodeOption option)
        {
            Table table = new Table(currentTable);
            StringBuilder sql = new StringBuilder();

            StoredProcedure sqlCreateEntitiy = new CreateEntitySP(option.CreateEntityStoredProcedureName, option.Author, option.Columns, option.IdColumn, table, option.GetNewAutoGUID);
            sql.AppendLine(sqlCreateEntitiy.Sql);
            sql.AppendLine();

            StoredProcedure sqlUpdateEntitiy = new UpdateEntitySP(option.UpdateEntityStoredProcedureName, option.Author, option.Columns, option.IdColumn, table);
            sql.AppendLine(sqlUpdateEntitiy.Sql);
            sql.AppendLine();

            if (option.CreateBatOperation)
            {
                StoredProcedure sqlCreateEntitiys = new BatCreateEntity(option.CreateEntityStoredProcedureName + "_Bat", option.Author, option.Columns, option.IdColumn, table, option.GetNewAutoGUID);
                sql.AppendLine(sqlCreateEntitiys.Sql);
                sql.AppendLine();

                StoredProcedure sqlUpdateEntitiys = new BatUpdateEntitySP(option.UpdateEntityStoredProcedureName + "_Bat", option.Author, option.Columns, option.IdColumn, table);
                sql.AppendLine(sqlUpdateEntitiys.Sql);
                sql.AppendLine();
            }

            StoredProcedure sqlDeleteEntitiy = new DeleteEntitySP(option.DeleteEntityStoredProcedureName, option.Author, option.IdColumn, table);
            sql.AppendLine(sqlDeleteEntitiy.Sql);
            sql.AppendLine();

            StoredProcedure sqlGetIds = new GetIdsSP(option.GetEntityIdsStoredProcedureName, option.Author, option.IdColumn, table);
            sql.AppendLine(sqlGetIds.Sql);
            sql.AppendLine();

            StoredProcedure sqlGetEntities = new GetEntitiesSP(option.GetEntitiesStoredProcedureName, option.Author, option.Columns, option.IdColumn, table);
            sql.AppendLine(sqlGetEntities.Sql);
            sql.AppendLine();

            editorStoredProcedures.Text = sql.ToString();
        }

        private CodeOption CodeOption
        {
            get
            {
                Column idColumn;
                List<Column> columns = GetSelectedColumns(out idColumn);
                CodeOption option = new CodeOption();
                option.Author = txtAuthor.Text;
                option.ClassName = txtClassName.Text;

                string preix = (ckbPreNameSpace.Checked && txtModelNameSpace.Tag != null && !string.IsNullOrEmpty(txtModelNameSpace.Tag.ToString().Trim())) ? txtModelNameSpace.Tag.ToString() : "";

                option.ModelNamespaceName = string.IsNullOrEmpty(txtModelNameSpace.Text.Trim()) ? FormatePreix(preix) : txtModelNameSpace.Text.Trim() + "." + FormatePreix(preix);
                option.BllNamespaceName = string.IsNullOrEmpty(txtBllNameSpace.Text.Trim()) ? FormatePreix(preix) : txtBllNameSpace.Text.Trim() + "." + FormatePreix(preix);
                option.DalNamespaceName = string.IsNullOrEmpty(txtDalNameSpace.Text.Trim()) ? FormatePreix(preix) : txtDalNameSpace.Text.Trim() + "." + FormatePreix(preix);

                option.DalClassName = FormatePreix(txtModelNameSpace.Tag.ToString()) + "DataProvider";
                option.FullTableName = txtClassName.Tag.ToString();
                option.ManagerClassName = txtManagerClassName.Text;
                option.GetEntitiesStoredProcedureName = txtGetEntitiesStoredProcedureName.Text;
                option.GetEntityIdsStoredProcedureName = txtGetIdsStoredProcedureName.Text;
                option.CreateEntityStoredProcedureName = txtCreateEntityStoredProcedureName.Text;
                option.UpdateEntityStoredProcedureName = txtUpdateEntityStoredProcedureName.Text;
                option.DeleteEntityStoredProcedureName = txtDeleteEntityStoredProcedureName.Text;
                option.GetNewAutoGUID = ckNeedAutoGuid.Checked;
                option.EnableParamCache = ckParamCache.Checked;
                option.ProtoBuf = ckProtoBuf.Checked;
                option.WithTrans = ckWithTrans.Checked;
                option.CreateBatOperation = ckBatOperation.Checked;
                option.IdColumn = idColumn;
                option.Columns = columns;
                option.IsBllSinglon = ckSingletonBLL.Checked;
                option.IsPartial = ckPartial.Checked;

                option.InitDalNameSpace = txtDalNameSpace.Text.Trim();

                return option;
            }
        }



        public CodeOption GetCodeOption(string tablename)
        {

            List<Column> columns = DataAccess.GetColumns(tablename);
            CodeOption option = new CodeOption();
            //  option.Author = txtAuthor.Text;
            option.ClassName = Coder.ConvertTablenameToClassname(tablename);

            string preix = ckbPreNameSpace.Checked ? Coder.GetTableNamePrefix(tablename) : "";

            option.ModelNamespaceName = string.IsNullOrEmpty(txtModelNameSpace.Text.Trim()) ? FormatePreix(preix) : txtModelNameSpace.Text.Trim() + "." + FormatePreix(preix);
            option.BllNamespaceName = string.IsNullOrEmpty(txtBllNameSpace.Text.Trim()) ? FormatePreix(preix) : txtBllNameSpace.Text.Trim() + "." + FormatePreix(preix);
            option.DalNamespaceName = txtDalNameSpace.Text.Trim();// string.IsNullOrEmpty(txtDalNameSpace.Text.Trim()) ? FormatePreix(preix) : txtDalNameSpace.Text.Trim() + "." + FormatePreix(preix);

            option.DalClassName = FormatePreix(Coder.GetTableNamePrefix(tablename)) + "DataProvider";
            option.FullTableName = tablename;
            option.ManagerClassName = option.ClassName + "Manager";
            option.GetEntitiesStoredProcedureName = Coder.ConverTablenameToGetEntitiesStoredProcedureName(tablename);

            option.CreateEntityStoredProcedureName = Coder.ConverTablenameToActEntityStoredProcedureName(tablename, "Create");
            option.UpdateEntityStoredProcedureName = Coder.ConverTablenameToActEntityStoredProcedureName(tablename, "Update");
            option.DeleteEntityStoredProcedureName = Coder.ConverTablenameToActEntityStoredProcedureName(tablename, "Delete");


            option.GetNewAutoGUID = ckNeedAutoGuid.Checked;
            option.EnableParamCache = ckParamCache.Checked;
            option.ProtoBuf = ckProtoBuf.Checked;
            option.WithTrans = ckWithTrans.Checked;
            option.CreateBatOperation = ckBatOperation.Checked;
            option.IdColumn = columns[0];
            option.Columns = columns;


            option.GetEntityIdsStoredProcedureName = Coder.ConverTablenameToGetIdsStoredProcedureName(tablename, option.IdColumn);

            option.IsBllSinglon = ckSingletonBLL.Checked;
            option.IsPartial = ckPartial.Checked;

            option.InitDalNameSpace = txtDalNameSpace.Text.Trim();
            return option;

        }


        private void tsbConnect_Click(object sender, EventArgs e)
        {
            frmConn con = new frmConn(this.LoadData);
            con.ShowDialog();
        }

        private void tsbExportDBDoc_Click(object sender, EventArgs e)
        {
            if (DataAccess.conn == string.Empty)
            {
                MessageBox.Show("请先连接数据库");
                tsbConnect_Click(sender, e);
                return;
            }

            frmDBDocument doc = new frmDBDocument();
            doc.ShowDialog();
        }

        private void tsbExportMarkCode_Click(object sender, EventArgs e)
        {
            Class c = new EnumClass();
            editorEntity.Text = c.Code;
        }

        private void tspCodeFiles_Click(object sender, EventArgs e)
        {
            frmGeCodeFiles frm = new frmGeCodeFiles();
            frm.mainForm = this;
            frm.ShowDialog();
        }

        private string FormatePreix(string preix)
        {
            if (string.IsNullOrEmpty(preix.Trim()))
            {
                return "";
            }
            return preix[0].ToString().ToUpper() + preix.Substring(1);
        }

    }
}
